package com.qyxx.platform.gsmng.common.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.impl.persistence.entity.HistoricTaskInstanceEntity;
import org.activiti.engine.impl.pvm.delegate.ActivityExecution;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.qyxx.platform.gsc.cache.SqlCache;
import com.qyxx.platform.gsc.utils.Constants;
import com.qyxx.platform.gsmng.common.dao.GsMngDao;
import com.qyxx.platform.sysmng.accountmng.dao.RoleDao;
import com.qyxx.platform.sysmng.accountmng.dao.UserDao;
import com.qyxx.platform.sysmng.accountmng.entity.Organization;
import com.qyxx.platform.sysmng.accountmng.entity.Role;
import com.qyxx.platform.sysmng.accountmng.entity.User;
import com.qyxx.platform.sysmng.exception.GsException;
import com.qyxx.platform.sysmng.notice.dao.NoticeDao;
import com.qyxx.platform.sysmng.notice.dao.NoticeToUserDao;
import com.qyxx.platform.sysmng.notice.entity.Notice;
import com.qyxx.platform.sysmng.notice.entity.NoticeToUser;
/**
 *发送消息处理类
 */
@Service
@Transactional
public class SendMessage {
	
	protected TaskService taskService;

	protected RuntimeService runtimeService;
	
	private NoticeDao noticeDao;
	
	private NoticeToUserDao noticeToUserDao;
	
	private UserDao userDao;
	
	private RoleDao roleDao;
	
	private HistoryService historyService;
	
	private GsMngManager gsMngManager;
	
	private GsMngDao gsMngDao;
	
	@Autowired
	public void setGsMngManager(GsMngManager gsMngManager) {
		this.gsMngManager = gsMngManager;
	}
	@Autowired
	public void setGsMngDao(GsMngDao gsMngDao) {
		this.gsMngDao = gsMngDao;
	}
	@Autowired
	public void setHistoryService(HistoryService historyService) {
		this.historyService = historyService;
	}
	@Autowired
	public void setRoleDao(RoleDao roleDao) {
		this.roleDao = roleDao;
	}
	
	@Autowired
	public void setNoticeToUserDao(NoticeToUserDao noticeToUserDao) {
		this.noticeToUserDao = noticeToUserDao;
	}

	@Autowired
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	@Autowired
	public void setNoticeDao(NoticeDao noticeDao) {
		this.noticeDao = noticeDao;
	}


	@Autowired
	public void setRuntimeService(RuntimeService runtimeService) {
		this.runtimeService = runtimeService;
	}

	@Autowired
	public void setTaskService(TaskService taskService) {
		this.taskService = taskService;
	}

	@Transactional
	public void sendRemind(ActivityExecution execution,String title,String roleName,String rptName){
		//发送提醒通知，查看流程历史
	/*	Notice notice = new Notice();
		notice.setKeyworlds("提醒");
		notice.setTitle(title);
		notice.setStatus(Notice.STATUS_1);
		notice.setStyle(Notice.STYLE_05);					
		notice.setCreateUser(1L);
		notice.setCreateTime(new Date());	
		notice.setContent(title);
		notice.setModuleDataId(execution.getProcessInstanceId());
		noticeDao.save(notice);	*/	
		HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(execution.getProcessInstanceId()).singleResult();
		String loginName =hpi.getStartUserId();
		User user = userDao.findUniqueBy("loginName", loginName);
		if (StringUtils.isNotBlank(roleName)) {//发送给主管提醒通知
			Role r = roleDao.findUniqueBy("roleName", roleName);
			List<User> userList = r.getUserList();
			Long userId = null;
			List<Long> userIdList = Lists.newArrayList();
			Organization onwerOrg = user.getOrganization();
			String onwerCode = onwerOrg.getOrganizationCode();
			for (User u : userList) {
				Organization org = u.getOrganization();
				String code = org.getOrganizationCode();
				if(onwerCode.indexOf(code)>=0 || code.indexOf(onwerCode)>=0){
					userId = u.getId();
					userIdList.add(userId);
				}else{
					userId = u.getId();
					userIdList.add(userId);
					break;
				}
			}
			for (Long uId : userIdList) {
			saveNotice(title,Notice.STYLE_05,execution.getProcessInstanceId(),null,rptName,uId);
			}
		} else if ("".equals(roleName)) {//发送给启动者
			saveNotice(title,Notice.STYLE_05,execution.getProcessInstanceId(),null,rptName,user.getId());
		}
	}
	
	@Transactional
	public void sendRemindByTaskName(ActivityExecution execution,String title,String taskName,String rptName){
		//根据历史任务的办理人，发送通知
		String processInstanceId = execution.getProcessInstanceId();
		HistoricTaskInstanceEntity htie =(HistoricTaskInstanceEntity) historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).taskName(taskName).singleResult();
		String loginName = htie.getAssignee();
		if (StringUtils.isNotBlank(loginName)) {
		User user = userDao.findUniqueBy("loginName", loginName);
		saveNotice(title,Notice.STYLE_05,processInstanceId,null,rptName,user.getId());
		}
	}
	
	@Transactional
	public void sendRemindByField(ActivityExecution execution,String title,String fieldKey){
		//根据当前单据中的指定字段的值，发送通知
		String businessKey = execution.getProcessBusinessKey();
		String a[] = businessKey.split("\\|");
		String bname = a[0];
		Long bid = Long.valueOf(a[1]);
		Map<String, Object> module = gsMngManager.getEntity(bid);
		Long uId = (Long)module.get(fieldKey);
		if (uId!=null) {		
		saveNotice(title,Notice.STYLE_05,a[1],bname,null,uId);
		}
	}
	
	/**
	 * 发送业务通知
	 * 
	 * @param execution
	 * @param title
	 * @param roleName
	 * @param entityName
	 */
	@Transactional
	public void sendBusinessRemind(ActivityExecution execution,String title,String roleName, String entityName){
		//根据当前单据中的指定字段的值，发送通知
		String businessKey = execution.getProcessBusinessKey();
		String a[] = businessKey.split("\\|");
		String bid = a[1];
		if (StringUtils.isNotBlank(roleName)) {//发送给非流程启动人	
			Role r = roleDao.findUniqueBy("roleName", roleName);
			List<User> userList = r.getUserList();
			for (User u : userList) {
				Long uId = u.getId();
				saveNotice(title,Notice.STYLE_06,bid,entityName,"true",uId);
			}
		} else {//发送给流程启动人
			String loginName= (String) execution.getVariable("startUser");
			User user = userDao.findUniqueBy("loginName", loginName);
			Long userId = user.getId();
			saveNotice(title,Notice.STYLE_06,bid,entityName,"true",userId);
		}
	}
	
	@SuppressWarnings("unchecked")
	@Transactional
	public void sendOrder(ActivityExecution execution,String title,String roleName){
		//发送下推生成的单据，查看下推生成的单据		
		String targetModel =  (String)execution.getVariable("targetModel");
		List<Long> masterIdList  =(List<Long>)execution.getVariable("masterIdList");
		List<String> moduleIdList = Lists.newArrayList();
		for(Long id : masterIdList){
			String mid = String.valueOf(id);
			moduleIdList.add(mid);
		}
		if (moduleIdList.size()>0) {
			for(String orderId : moduleIdList){
		/*		Notice notice = new Notice();
				notice.setKeyworlds("提醒");
				notice.setTitle(title);
				notice.setStatus(Notice.STATUS_1);
				notice.setStyle(Notice.STYLE_06);					
				notice.setCreateUser(1L);
				notice.setCreateTime(new Date());	
				notice.setContent(title);
				notice.setModuleDataId(orderId);
				notice.setModuleKey(targetModel);
				noticeDao.save(notice);	*/
				gsMngManager.setEntityName(targetModel);
				Map<String, Object> map = gsMngManager.getEntity(NumberUtils.toLong(orderId));
				Long owner = (Long) map.get("createUser");
				if (StringUtils.isNotBlank(roleName)) {//发送给非流程启动人	
					Role r = roleDao.findUniqueBy("roleName", roleName);
					List<User> userList = r.getUserList();
					for (User u : userList) {
						Long uId = u.getId();
						 if(owner.equals(uId)){
							 saveNotice(title,Notice.STYLE_06,orderId,targetModel,"true",uId);
						 }else{
							 saveNotice(title,Notice.STYLE_06,orderId,targetModel,"false",uId);
						 }
					}
				
				}else{//发送给流程启动人				
					Long createUserId = (Long)execution.getVariable("createUser");
					saveNotice(title,Notice.STYLE_06,orderId,targetModel,"true",createUserId);
				}
			
			}	
		}
	}
	@SuppressWarnings("unchecked")
	@Transactional
	public void sendOrderByTaskName(ActivityExecution execution,String title,String taskName){
		//通过历史任务，发送通知查看下推生成的单据		
		String processInstanceId = execution.getProcessInstanceId();
		String targetModel =  (String)execution.getVariable("targetModel");
		List<Long> masterIdList  =(List<Long>)execution.getVariable("masterIdList");
		List<String> moduleIdList = Lists.newArrayList();
		for(Long id : masterIdList){
			String mid = String.valueOf(id);
			moduleIdList.add(mid);
		}
		HistoricTaskInstanceEntity htie =(HistoricTaskInstanceEntity) historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).taskName(taskName).singleResult();
		String loginName = htie.getAssignee();
		Long userId = null;
		if (StringUtils.isNotBlank(loginName)) {
			User user = userDao.findUniqueBy("loginName", loginName);
			userId = user.getId();
		}
		if (moduleIdList.size()>0) {
			gsMngManager.setEntityName(targetModel);
			for(String orderId : moduleIdList){
				 Map<String, Object> map = gsMngManager.getEntity(NumberUtils.toLong(orderId));
				 Long owner = (Long) map.get("createUser");
				 if(owner.equals(userId)){//表示发送业务通知给单据的拥有者
					 saveNotice(title,Notice.STYLE_06,orderId,targetModel,"true",userId);
				 }else{//表示发送业务通知给单据的非拥有者
					 saveNotice(title,Notice.STYLE_06,orderId,targetModel,"false",userId);
				 }
			}	
		}
	}
	@SuppressWarnings("unchecked")
	@Transactional
	public void sendOrderByStarter(ActivityExecution execution,String title){
		
		String targetModel =  (String)execution.getVariable("targetModel");
		List<Long> masterIdList  =(List<Long>)execution.getVariable("masterIdList");
		List<String> moduleIdList = Lists.newArrayList();
		for(Long id : masterIdList){
			String mid = String.valueOf(id);
			moduleIdList.add(mid);
		}
		String	loginName= (String) execution.getVariable("startUser");	
		User user = userDao.findUniqueBy("loginName", loginName);
		Long userId = user.getId();

		if (moduleIdList.size()>0) {
			gsMngManager.setEntityName(targetModel);
			for(String orderId : moduleIdList){								
				 saveNotice(title,Notice.STYLE_06,orderId,targetModel,"false",userId);			 
			}	
		}
	}
	/**
	 * 公用创建通知对象
	 * 
	 */
	public void saveNotice(String title,String style,String moduleDataId,String moduleKey,String moduleFields,Long userId){
		Notice notice = new Notice();
		notice.setKeyworlds("提醒");
		notice.setTitle(title);
		notice.setStatus(Notice.STATUS_1);
		notice.setStyle(style);					
		notice.setCreateUser(1L);
		notice.setCreateTime(new Date());	
		notice.setContent(title);
		notice.setModuleDataId(moduleDataId);
		notice.setModuleKey(moduleKey);
		notice.setModuleFields(moduleFields);
		noticeDao.save(notice);	
		
		NoticeToUser noticeToUser = new NoticeToUser();
		noticeToUser.setNotice(notice);
		noticeToUser.setStatus(NoticeToUser.STATUS_0);
		noticeToUser.setUserId(userId);
		noticeToUserDao.save(noticeToUser);
	}
	
	/**
	 * 发送通知
	 * 
	 * @param title
	 * @param content
	 * @param style
	 * @param moduleDataId
	 * @param moduleKey
	 * @param moduleFields
	 * @param userIds
	 */
	public void saveNotice(String title, String content, String style,String moduleDataId,String moduleKey,String moduleFields,List<Long> userIds){
		Notice notice = new Notice();
		notice.setKeyworlds("提醒");
		notice.setTitle(title);
		notice.setStatus(Notice.STATUS_1);
		notice.setStyle(style);					
		notice.setCreateUser(1L);
		notice.setCreateTime(new Date());	
		notice.setContent(title);
		notice.setModuleDataId(moduleDataId);
		notice.setModuleKey(moduleKey);
		notice.setModuleFields(moduleFields);
		noticeDao.save(notice);
		if(userIds != null) {
			for(Long userId : userIds) {
				NoticeToUser noticeToUser = new NoticeToUser();
				noticeToUser.setNotice(notice);
				noticeToUser.setStatus(NoticeToUser.STATUS_0);
				noticeToUser.setUserId(userId);
				noticeToUserDao.save(noticeToUser);
			}
		}
	}
	
	/**
	 * 发送通知方法
	 * 
	 * @param execution
	 * @param titleSqlKey 查询通知标题sql语句key
	 * @param contentSqlKey 查询通知内容sql语句key 
	 * @param userSqlKey 查询通知用户sql语句key
	 * @param noticeStyle 通知类型
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public void sendNotice(ActivityExecution execution,String titleSqlKey,String contentSqlKey,String userSqlKey, String noticeStyle){
		//根据当前单据中的指定字段的值，发送通知
		String businessKey = execution.getProcessBusinessKey();
		String a[] = businessKey.split("\\|");
		String bid = a[1];
		String entityName = a[0];
		String sqlKeyTitle = Constants.RULE_SUFFIX + Constants.NAME_SPLIT_SYMBOL + titleSqlKey;
		final String namedSqlTitle = SqlCache.getInstance().getSqlContent(sqlKeyTitle);
		if(StringUtils.isBlank(namedSqlTitle)) {
			throw new GsException(sqlKeyTitle + "对应的标题sql找不到");
		}
		String sqlKeyContent = Constants.RULE_SUFFIX + Constants.NAME_SPLIT_SYMBOL + contentSqlKey;
		final String namedSqlContent = SqlCache.getInstance().getSqlContent(sqlKeyContent);
		if(StringUtils.isBlank(namedSqlContent)) {
			throw new GsException(sqlKeyContent + "对应的内容sql找不到");
		}
		String sqlKeyUser = Constants.RULE_SUFFIX + Constants.NAME_SPLIT_SYMBOL + userSqlKey;
		final String namedSqlUser = SqlCache.getInstance().getSqlContent(sqlKeyUser);
		if(StringUtils.isBlank(namedSqlUser)) {
			throw new GsException(sqlKeyUser + "对应的用户sql找不到");
		}
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("id", bid);
		String title = (String)gsMngDao.createSQLQuery(namedSqlTitle, param).uniqueResult();
		String content = (String)gsMngDao.createSQLQuery(namedSqlContent, param).uniqueResult();
		List<Number> userIdList = (List<Number>)gsMngDao.createSQLQuery(namedSqlUser, param).list();
		List<Long> userIds = new ArrayList<Long>();
		if(userIds !=null) {
			for(Number userId : userIdList) {
				userIds.add(userId.longValue());
			}
		}
		saveNotice(title,content, noticeStyle,bid,entityName,"true", userIds);
	}
}
